// threadPool.c
#include "threadPool.h"
#define _LISTEN_QUEUE_SIZE 16

void work(const int netfd){
    // 传输文件
    printf("working...\n");
}

void* _threadFunc(void* threadPool){
    if(threadPool == NULL){
        printf("input parameter error.\n");
        return NULL;
    }
    threadPool_t* pool = (threadPool_t*)threadPool;
    _dirStack_t dirStack;
    _dirStack_init(&dirStack);
    int netfd = -1;
    while(1){
        pthread_mutex_lock(&pool->_mutex);
        while(pool->_exitFlag == 0 && _taskQueue_is_empty(&pool->_q)){
            pthread_cond_wait(&pool->_cond, &pool->_mutex);
            /* printf("flag = %d\n", pool->_exitFlag); */
        }
        // exit
        if(pool->_exitFlag == 1){
            printf("recv quit from parent proccess, worker exit.\n");
            close(netfd);
            pthread_mutex_unlock(&pool->_mutex);
            pthread_exit(NULL);
        }
        task_t* newTask = _taskQueue_front(&pool->_q);
        user_t* user = newTask->_user;
        _taskQueue_deque(&pool->_q);
        /* printf("worker: netfd = %d, tid = %lu\n", newTask->_clientFd, pthread_self()); */
        pthread_mutex_unlock(&pool->_mutex);

        //work(netfd);
        
        // 保存当前路径
        
        if(user){
            doTask(newTask, &user->_dirStack);
            free(newTask);
        }
    }
    return NULL;
}

void threadPool_init(threadPool_t* pool, int workerNum){
    pthread_mutex_init(&pool->_mutex, NULL);
    pthread_cond_init(&pool->_cond, NULL);
    _taskQueue_init(&pool->_q);
    _tidArr_init(&pool->_tidArr, workerNum);
    pool->_exitFlag = 0;
    int res = 0;
    for(int i = 0;i < pool->_tidArr._worker_num; ++i){
        res = pthread_create(&pool->_tidArr._arr[i], NULL, _threadFunc, pool);// 直接传pool
        ERROR_CHECK(res, -1, "pthread_create");
    }
    //printf("threadPool_init success.\n");// test only
}

int tcp_init(const char* ip, const char* port){
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(sockfd, -1, "socket");
    int flag = 1;
    int res = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));

    ERROR_CHECK(res, -1, "setsockopt");
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip);
    addr.sin_port = htons(atoi(port));
    res = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    ERROR_CHECK(res, -1, "bind");

    res = listen(sockfd, _LISTEN_QUEUE_SIZE);
    ERROR_CHECK(res, -1, "listen");

    //printf("tcp_init success.\n");// test only

    return sockfd;
}

int epollAdd(int epfd,int fd)
{
    struct epoll_event ev;
    ev.data.fd = fd;
    ev.events = EPOLLIN;
    int epoll_ctl_res = epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&ev);
    ERROR_CHECK(epoll_ctl_res,-1,"epoll add error");
    return 0;
}

int epollDel(int epfd,int fd)
{
    int epoll_ctl_res = epoll_ctl(epfd,EPOLL_CTL_DEL,fd,NULL);
    ERROR_CHECK(epoll_ctl_res,-1,"epoll delete error");
    return 0;
}

/* int main() */
/* { */
/*     threadPool_t pool; */
/*     int workerNum = 10; */
/*     char ip[] = "192.168.238.128"; */
/*     char port[] = "12345"; */
/*     threadPool_init(&pool, workerNum); */
/*     int sockfd = tcp_init(ip, port); */
/*     if (sockfd < 0) { */
/*         fprintf(stderr, "tcp_init failed\n"); */
/*         return -1; */
/*     } */
/*     return 0; */
/* } */

